package com.heart.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heart.common.constant.AppConstant;
import com.heart.common.utils.*;
import com.heart.dao.entity.*;
import com.heart.dao.mapper.*;
import com.heart.service.QuestionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Service
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements QuestionService {

    @Autowired
    private QuestionMapper questionMapper;
    @Autowired
    private QuestionDetailMapper questionDetailMapper;
    @Autowired
    private QuestionDetailItemMapper questionDetailItemMapper;
    @Autowired
    private QuestionLogicMapper questionLogicMapper;
    @Autowired
    private AnswerMainMapper answerMainMapper;
    @Autowired
    private SecurityUserMapper securityUserMapper;

    public Integer getDashboardNumber(String type){
        if (AppConstant.LOGIN_TIMES.equals(type)) {
            return securityUserMapper.loginTimes();
        } else if(AppConstant.UNPUBLISH_TIMES.equals(type)){
            return  questionMapper.questionTimes(AppConstant.ZORE);
        } else if(AppConstant.PUBLISH_TIMES.equals(type)){
            return  questionMapper.questionTimes(AppConstant.ONE);
        } else if (AppConstant.ANSWER_TIMES.equals(type)){
            return  answerMainMapper.answerTimes();
        }
        return 0;
    }

    public Map<String,Map<String,List<Integer>>> getDashboardListNumber(){
        Date now = new Date();
        Date start =  DateTimeUtils.addDates(now, -6);
        List<String> listDates = DateTimeUtils.dateFomartList(start, now);
        List<Integer> loginTimes = securityUserMapper.loginTimesList(listDates);
        List<Integer> unpublishTimes = questionMapper.questionTimesList(AppConstant.ZORE, listDates);
        List<Integer> publishTimes = questionMapper.questionTimesList(AppConstant.ONE, listDates);
        List<Integer> answerTimes =  answerMainMapper.answerTimesList(listDates);

        Map<String,List<Integer>> loginTimesMaps = new HashMap<>();
        loginTimesMaps.put(AppConstant.EXPECTEDDATA, loginTimes);

        Map<String,List<Integer>> unpublishTimesMaps = new HashMap<>();
        unpublishTimesMaps.put(AppConstant.EXPECTEDDATA, unpublishTimes);

        Map<String,List<Integer>> publishTimesMaps = new HashMap<>();
        publishTimesMaps.put(AppConstant.EXPECTEDDATA, publishTimes);

        Map<String,List<Integer>> answerTimesMaps = new HashMap<>();
        answerTimesMaps.put(AppConstant.EXPECTEDDATA, answerTimes);

        Map<String,Map<String,List<Integer>>> maps = new LinkedHashMap<>();
        maps.put(AppConstant.LOGIN_TIMES, loginTimesMaps);
        maps.put(AppConstant.UNPUBLISH_TIMES, unpublishTimesMaps);
        maps.put(AppConstant.PUBLISH_TIMES, publishTimesMaps);
        maps.put(AppConstant.ANSWER_TIMES, answerTimesMaps);

        return maps;
    }


    public List<Question> getQuestionListByUserCode(String userCode){
        QueryWrapper<Question> wrapper = new QueryWrapper<>();
        wrapper.and(entity -> entity.eq("tc_create_user_code", userCode).or().eq("tc_is_public", AppConstant.ONE));
        wrapper.and(entity -> entity.isNull("tc_complete_delete_status").or().ne("tc_complete_delete_status", AppConstant.ONE));
        List<Question> questionList = questionMapper.selectList(wrapper);
        AssertUtils.notNull(questionList, "查询的问卷不存在");
        return questionList;
    }

    public List<QuestionDetail> getQuestionDetailListByQuestionId(String questionId){
        QueryWrapper<QuestionDetail> wrapperDetail = new QueryWrapper<>();
        wrapperDetail.eq("tc_question_id", questionId);
        List<QuestionDetail> questionDetails = questionDetailMapper.selectList(wrapperDetail);
        if(ObjectUtils.isNull(questionDetails)){
        } else {
            questionDetails.forEach(questionDetail -> {
                QueryWrapper<QuestionDetailItem> wrapperItem = new QueryWrapper<>();
                wrapperItem.eq("tc_detail_id", questionDetail.getDetailId());
                List<QuestionDetailItem> questionDetailItems = questionDetailItemMapper.selectList(wrapperItem);
                if(ObjectUtils.isNull(questionDetailItems)){
                    questionDetail.setQuestionDetailItemList(new ArrayList<>());
                } else {
                    questionDetail.setQuestionDetailItemList(questionDetailItems);
                }

                QueryWrapper<QuestionLogic> wrapperLogic = new QueryWrapper<>();
                wrapperLogic.eq("tc_detail_id", questionDetail.getDetailId());
                List<QuestionLogic> questionLogicList = questionLogicMapper.selectList(wrapperLogic);
                if(ObjectUtils.isNull(questionLogicList)){
                    questionDetail.setQuestionLogicList(new ArrayList<>());
                } else {
                    questionDetail.setQuestionLogicList(questionLogicList);
                }
            });
        }
        return questionDetails;
    }

    public  boolean updateQuestion(Question question){
        if(ObjectUtils.isNotNull(question)) {
            questionMapper.deleteById(question.getQuestionId());
            if(CollectionUtils.isNotEmpty(question.getQuestionDetailList())){
                QueryWrapper<QuestionDetail> wrapperQuestionDetail = new QueryWrapper<>();
                wrapperQuestionDetail.eq("tc_question_id",question.getQuestionId());
                questionDetailMapper.delete(wrapperQuestionDetail);
                question.getQuestionDetailList().forEach(m -> {
                    QueryWrapper<QuestionDetailItem> wrapperQuestionDetailItem = new QueryWrapper<>();
                    wrapperQuestionDetailItem.eq("tc_detail_id", m.getDetailId());
                    questionDetailItemMapper.delete(wrapperQuestionDetailItem);

                    QueryWrapper<QuestionLogic> wrapperLogic = new QueryWrapper<>();
                    wrapperLogic.eq("tc_detail_id", m.getDetailId());
                    questionLogicMapper.delete(wrapperLogic);
                });
            }
        }
        questionMapper.insert(question);
        if(CollectionUtils.isNotEmpty(question.getQuestionDetailList())){
            question.getQuestionDetailList().forEach(m-> {
                m.setQuestionId(question.getQuestionId());
                questionDetailMapper.insert(m);

                if(CollectionUtils.isNotEmpty(m.getQuestionDetailItemList())){
                    m.getQuestionDetailItemList().forEach(n-> {
                        n.setDetailId(m.getDetailId());
                        questionDetailItemMapper.insert(n);
                    });
                }

                if(CollectionUtils.isNotEmpty(m.getQuestionLogicList())){
                    m.getQuestionLogicList().forEach(n-> {
                        n.setDetailId(m.getDetailId());
                        questionLogicMapper.insert(n);
                    });
                }
            });
        }
        return true;
    }

    public boolean updateQuestionSetting(Question question) {
        UpdateWrapper<Question> wrapper = new UpdateWrapper();
        wrapper.eq("tc_question_id", question.getQuestionId());
        wrapper.set("tc_frequency_limit_type", question.getFrequencyLimitType());
        wrapper.set("tc_frequency_limit_num", question.getFrequencyLimitNum());
        wrapper.set("tc_date_limit_type", question.getDateLimitType());
        wrapper.set("tc_date_limit_start", question.getDateLimitStart());
        wrapper.set("tc_date_limit_end", question.getDateLimitEnd());
        wrapper.set("tc_is_public", question.getIsPublic());
      return  questionMapper.update(null, wrapper) > 0;
    }

    /**
     * 发布问卷
     * @param question
     * @return
     */
    public boolean publishQuestion(Question question){
        UpdateWrapper<Question> wrapper = new UpdateWrapper();
        wrapper.eq("tc_question_id", question.getQuestionId());
        wrapper.set("tc_question_status", question.getQuestionStatus());
        wrapper.set("tc_release_time", new Date());
        return  questionMapper.update(null, wrapper) > 0;
    }
    public  boolean deleteQuestion(Question question){
        UpdateWrapper<Question> wrapper = new UpdateWrapper();
        wrapper.eq("tc_question_id", question.getQuestionId());
        wrapper.set("tc_delete_status", question.getDeleteStatus());
        wrapper.set("tc_delete_time", new Date());
        return  questionMapper.update(null, wrapper) > 0;
    }
    public  boolean completeDeleteQuestion(Question question){
        UpdateWrapper<Question> wrapper = new UpdateWrapper();
        wrapper.eq("tc_question_id", question.getQuestionId());
        wrapper.set("tc_complete_delete_status", question.getCompleteDeleteStatus());
        wrapper.set("tc_complete_delete_time", new Date());
        return  questionMapper.update(null, wrapper) > 0;
    }
    public boolean saveQuestion(Question question){
        if(ObjectUtils.isNull(question)){
            return false;
        }
        if(ObjectUtils.isNotNull(question.getQuestionId()) && question.getQuestionId() > 0) {
            questionMapper.deleteById(question.getQuestionId());
        }
        String uuid = RandomUtils.simpleUuid();
        question.setCreateTime(new Date());
        question.setUuid(uuid);
        return questionMapper.insert(question) > 0;
    }
    public  boolean copyQuestion(Question question){
        if(ObjectUtils.isNull(question)){
            return false;
        }
        if(ObjectUtils.isNull(question.getQuestionId())){
            return false;
        }
        if(question.getQuestionId()<=0) {
            return false;
        }

        List<QuestionDetail> questionDetailList = getQuestionDetailListByQuestionId(question.getQuestionId().toString());
        question.setQuestionId(null);
        question.setQuestionNumber(0);
        question.setUuid(RandomUtils.simpleUuid());
        question.setCreateTime(new Date());
        questionMapper.insert(question);
        if(CollectionUtils.isNotEmpty(questionDetailList)){
            questionDetailList.forEach(m-> {
                m.setQuestionId(question.getQuestionId());
                m.setDetailId(null);
                questionDetailMapper.insert(m);

                if(CollectionUtils.isNotEmpty(m.getQuestionDetailItemList())){
                    m.getQuestionDetailItemList().forEach(n-> {
                        n.setDetailId(m.getDetailId());
                        n.setItemId(null);
                        questionDetailItemMapper.insert(n);
                    });
                }

                if(CollectionUtils.isNotEmpty(m.getQuestionLogicList())){
                    m.getQuestionLogicList().forEach(n-> {
                        n.setDetailId(m.getDetailId());
                        n.setLogicId(null);
                        questionLogicMapper.insert(n);
                    });
                }
            });
        }
        return true;
    }

    public Question getQuestionAndDetailById(Integer questionId){
        AssertUtils.notNull(questionId, "问卷ID不能为空");
        Question question = questionMapper.selectById(questionId);
        if(ObjectUtils.isNull(question)){
            return null;
        }
        List<QuestionDetail> questionDetailList = getQuestionDetailListByQuestionId(questionId.toString());
        if(CollectionUtils.isEmpty(questionDetailList)){
            question.setQuestionDetailList(new ArrayList<>());
        } else {
            question.setQuestionDetailList(questionDetailList);
        }
        return question;
    }
    public Question getQuestionById(Integer questionId){
        AssertUtils.notNull(questionId, "问卷ID不能为空");
        return questionMapper.selectById(questionId);
    }

    public boolean validateQuestionLimit(HttpServletRequest request,String questionId){
        AssertUtils.notNull(questionId, "问卷ID不能为空");
        Question question = questionMapper.selectById(questionId);
        // 2 浏览器cookie方式 3 IP地址限制
        if(AppConstant.TWO.equals(question.getFrequencyLimitType()) || AppConstant.THREE.equals(question.getFrequencyLimitType())){
            String limit = AppConstant.EMPTY;
            QueryWrapper<AnswerMain> wrapper = new QueryWrapper<>();
            if(AppConstant.THREE.equals(question.getFrequencyLimitType())){
                limit = IPUtils.getIpAddr(request);
                wrapper.eq("tc_main_ip", limit);
            } else {
                limit = question.getUuid();
                wrapper.eq("tc_main_session_id", limit);
            }
            Integer count = answerMainMapper.selectCount(wrapper);
            if (count>= question.getFrequencyLimitNum()){
                return false;
            }
        }

        // 时间限制
        if(AppConstant.TWO.equals(question.getDateLimitType())){
            Date now = new Date();
            if (now.compareTo(question.getDateLimitStart()) < 0) {
                return false;
            }
            if (now.compareTo(question.getDateLimitStart()) > 0) {
                return false;
            }
        }

        return true;
    }
}
